package cn.elwy.rcp.ui.table.setting;

import java.util.List;

import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;

import cn.elwy.rcp.core.model.ui.InputModel;
import cn.elwy.rcp.ui.table.TableConfigFactory;
import cn.elwy.rcp.ui.table.TablePane;
import cn.elwy.rcp.ui.table.TablePaneFactory;
import cn.elwy.rcp.ui.table.model.ColumnInfo;
import cn.elwy.rcp.ui.table.model.TableConfig;

public class ColumnSettingDialog extends TitleAreaDialog {

  private static final String tablePaneId = "cn.elwy.rcp.ui.table.setting.TablePaneConfig";
  private String shellTitle;
  private final String discription;

  private Button upButton;
  private Button downButton;
  private Button topButton;
  private Button bottomButton;
  private Button selectAllButton;
  private Button deselectAllButton;
  private TablePane columnTablePane;
  private List<ColumnInfo> columns;
  private TableConfig tableConfig;

  public ColumnSettingDialog(Shell shell, String title, String description, TablePane tablePane) {
    super(shell);
    this.shellTitle = title;
    this.discription = description;
    tablePane.resetColumns();
    tableConfig = TableConfigFactory.newTableConfig(tablePane.getTableInfo());
    columns = tableConfig.getColumnInfoList();
  }

  @Override
  protected Control createDialogArea(Composite parent) {
    getShell().setText(shellTitle);
    setTitle(discription);

    Composite composite = new Composite(parent, SWT.BORDER);
    GridLayout gridLayout = new GridLayout(2, false);
    gridLayout.marginWidth = 20;
    gridLayout.marginTop = 10;
    composite.setLayout(gridLayout);
    composite.setLayoutData(new GridData(GridData.FILL_BOTH));

    columnTablePane = TablePaneFactory.getTablePane(composite, tablePaneId);
    columnTablePane.setLayoutData(new GridData(GridData.FILL_BOTH));
    columnTablePane.setInputModel(new InputModel(columns));

    Composite buttonComposite = new Composite(composite, SWT.NONE);
    buttonComposite.setLayout(new GridLayout(1, true));

    SelectionListener listener = new ButtonHandler();
    upButton = createButton(buttonComposite, "向上", listener, new GridData(80, 24));
    downButton = createButton(buttonComposite, "向下", listener, new GridData(80, 24));
    new Label(buttonComposite, SWT.NONE);
    topButton = createButton(buttonComposite, "置顶", listener, new GridData(80, 24));
    bottomButton = createButton(buttonComposite, "置底", listener, new GridData(80, 24));
    new Label(buttonComposite, SWT.NONE);
    selectAllButton = createButton(buttonComposite, "全部选中", listener, new GridData(80, 24));
    deselectAllButton = createButton(buttonComposite, "全部取消", listener, new GridData(80, 24));

    columnTablePane.addSelectionChangedListener(new ColumnSettingSelectionListener());
    columnTablePane.addCheckStateListener(new ColumnSettingCheckListener());
    return composite;
  }

  private Button createButton(Composite parent, String text, SelectionListener listener, GridData buttonData) {
    Button button = new Button(parent, SWT.NONE);
    button.setText(text);
    button.setLayoutData(buttonData);
    button.addSelectionListener(listener);
    return button;
  }

  /** 设置窗口居中 */
  @Override
  protected Point getInitialLocation(Point initialSize) {
    Rectangle shellBounds = null;
    if (getParentShell() == null) {
      shellBounds = Display.getCurrent().getBounds();
    } else {
      shellBounds = getParentShell().getBounds();
    }
    Point dialogSize = this.getInitialSize();
    return new Point(shellBounds.x + (shellBounds.width - dialogSize.x) / 2, shellBounds.y
        + (shellBounds.height - dialogSize.y) / 2);
  }

  /** 设置窗口初始化大小 */
  @Override
  protected Point getInitialSize() {
    return new Point(1000, 600);
  }

  @Override
  protected void setShellStyle(int newShellStyle) {
    super.setShellStyle(newShellStyle | SWT.DIALOG_TRIM | SWT.MAX | SWT.RESIZE | SWT.APPLICATION_MODAL);
  }

  @Override
  protected void okPressed() {
    super.okPressed();
  }

  public TableConfig getTablePaneConfig() {
    return tableConfig;
  }

  private void updateButtonStates() {
    Object selectionData = columnTablePane.getSelectionData();
    if (selectionData == null || columns == null || columns.isEmpty()) {
      setButtonState(false, false, false, false);
      return;
    }
    int index = columns.indexOf(selectionData);
    if (index == 0) {
      setButtonState(false, true, false, true);
    } else if (index == columns.size() - 1) {
      setButtonState(true, false, true, false);
    } else {
      setButtonState(true, true, true, true);
    }
  }

  private void setButtonState(boolean up, boolean down, boolean top, boolean bottom) {
    upButton.setEnabled(up);
    downButton.setEnabled(down);
    topButton.setEnabled(top);
    bottomButton.setEnabled(bottom);
  }

  private final class ButtonHandler extends SelectionAdapter {

    @Override
    public void widgetSelected(SelectionEvent e) {
      ColumnInfo selectionData = (ColumnInfo) columnTablePane.getSelectionData();
      if (selectionData == null || columns == null || columns.isEmpty()) {
        return;
      }
      updateColumnModels(e.widget, selectionData);
      columnTablePane.refresh();
      updateButtonStates();
      columnTablePane.setFocus();
    }

    private void updateColumnModels(Widget widget, ColumnInfo selectionData) {
      int index = columns.indexOf(selectionData);
      if (widget == upButton) {
        if (columns.size() > 1) {
          columns.remove(selectionData);
          columns.add(index - 1, selectionData);
        }
      } else if (widget == downButton) {
        if (columns.size() > 1) {
          columns.remove(selectionData);
          columns.add(index + 1, selectionData);
        }
      } else if (widget == topButton) {
        columns.remove(selectionData);
        columns.add(0, selectionData);
      } else if (widget == bottomButton) {
        columns.remove(selectionData);
        columns.add(selectionData);
      } else if (widget == selectAllButton) {
        for (ColumnInfo c : columns) {
          c.setVisible(true);
        }
      } else if (widget == deselectAllButton) {
        for (ColumnInfo c : columns) {
          c.setVisible(false);
        }
      }

      if (widget != selectAllButton && widget != deselectAllButton) {
        for (int i = 0; i < columns.size(); i++) {
          columns.get(i).setOrder(i);
        }
      }
    }
  }

  private class ColumnSettingSelectionListener implements ISelectionChangedListener {

    @Override
    public void selectionChanged(SelectionChangedEvent event) {
      updateButtonStates();
    }
  }

  public class ColumnSettingCheckListener implements ICheckStateListener {

    @Override
    public void checkStateChanged(CheckStateChangedEvent event) {
      ColumnInfo element = (ColumnInfo) event.getElement();
      element.setVisible(event.getChecked());
    }
  }
}
